home *** CD-ROM | disk | FTP | other *** search
/ Introduction to 3D Game …ogramming with DirectX 12 / Introduction-to-3D-Game-Programming-with-DirectX-12.ISO / Code.Textures / Chapter 12 The Geometry Shader / TreeBillboards / Shaders / TreeSprite.hlsl < prev   
Text File  |  2016-03-02  |  6KB  |  209 lines

  1. //***************************************************************************************
  2. // TreeSprite.hlsl by Frank Luna (C) 2015 All Rights Reserved.
  3. //***************************************************************************************
  4.  
  5. // Defaults for number of lights.
  6. #ifndef NUM_DIR_LIGHTS
  7.     #define NUM_DIR_LIGHTS 3
  8. #endif
  9.  
  10. #ifndef NUM_POINT_LIGHTS
  11.     #define NUM_POINT_LIGHTS 0
  12. #endif
  13.  
  14. #ifndef NUM_SPOT_LIGHTS
  15.     #define NUM_SPOT_LIGHTS 0
  16. #endif
  17.  
  18. // Include structures and functions for lighting.
  19. #include "LightingUtil.hlsl"
  20.  
  21. Texture2DArray gTreeMapArray : register(t0);
  22.  
  23.  
  24. SamplerState gsamPointWrap        : register(s0);
  25. SamplerState gsamPointClamp       : register(s1);
  26. SamplerState gsamLinearWrap       : register(s2);
  27. SamplerState gsamLinearClamp      : register(s3);
  28. SamplerState gsamAnisotropicWrap  : register(s4);
  29. SamplerState gsamAnisotropicClamp : register(s5);
  30.  
  31. // Constant data that varies per frame.
  32. cbuffer cbPerObject : register(b0)
  33. {
  34.     float4x4 gWorld;
  35.     float4x4 gTexTransform;
  36. };
  37.  
  38. // Constant data that varies per material.
  39. cbuffer cbPass : register(b1)
  40. {
  41.     float4x4 gView;
  42.     float4x4 gInvView;
  43.     float4x4 gProj;
  44.     float4x4 gInvProj;
  45.     float4x4 gViewProj;
  46.     float4x4 gInvViewProj;
  47.     float3 gEyePosW;
  48.     float cbPerObjectPad1;
  49.     float2 gRenderTargetSize;
  50.     float2 gInvRenderTargetSize;
  51.     float gNearZ;
  52.     float gFarZ;
  53.     float gTotalTime;
  54.     float gDeltaTime;
  55.     float4 gAmbientLight;
  56.  
  57.     float4 gFogColor;
  58.     float gFogStart;
  59.     float gFogRange;
  60.     float2 cbPerObjectPad2;
  61.  
  62.     // Indices [0, NUM_DIR_LIGHTS) are directional lights;
  63.     // indices [NUM_DIR_LIGHTS, NUM_DIR_LIGHTS+NUM_POINT_LIGHTS) are point lights;
  64.     // indices [NUM_DIR_LIGHTS+NUM_POINT_LIGHTS, NUM_DIR_LIGHTS+NUM_POINT_LIGHT+NUM_SPOT_LIGHTS)
  65.     // are spot lights for a maximum of MaxLights per object.
  66.     Light gLights[MaxLights];
  67. };
  68.  
  69. cbuffer cbMaterial : register(b2)
  70. {
  71.     float4   gDiffuseAlbedo;
  72.     float3   gFresnelR0;
  73.     float    gRoughness;
  74.     float4x4 gMatTransform;
  75. };
  76.  
  77. struct VertexIn
  78. {
  79.     float3 PosW  : POSITION;
  80.     float2 SizeW : SIZE;
  81. };
  82.  
  83. struct VertexOut
  84. {
  85.     float3 CenterW : POSITION;
  86.     float2 SizeW   : SIZE;
  87. };
  88.  
  89. struct GeoOut
  90. {
  91.     float4 PosH    : SV_POSITION;
  92.     float3 PosW    : POSITION;
  93.     float3 NormalW : NORMAL;
  94.     float2 TexC    : TEXCOORD;
  95.     uint   PrimID  : SV_PrimitiveID;
  96. };
  97.  
  98. VertexOut VS(VertexIn vin)
  99. {
  100.     VertexOut vout;
  101.  
  102.     // Just pass data over to geometry shader.
  103.     vout.CenterW = vin.PosW;
  104.     vout.SizeW   = vin.SizeW;
  105.  
  106.     return vout;
  107. }
  108.  
  109.  // We expand each point into a quad (4 vertices), so the maximum number of vertices
  110.  // we output per geometry shader invocation is 4.
  111. [maxvertexcount(4)]
  112. void GS(point VertexOut gin[1], 
  113.         uint primID : SV_PrimitiveID, 
  114.         inout TriangleStream<GeoOut> triStream)
  115. {    
  116.     //
  117.     // Compute the local coordinate system of the sprite relative to the world
  118.     // space such that the billboard is aligned with the y-axis and faces the eye.
  119.     //
  120.  
  121.     float3 up = float3(0.0f, 1.0f, 0.0f);
  122.     float3 look = gEyePosW - gin[0].CenterW;
  123.     look.y = 0.0f; // y-axis aligned, so project to xz-plane
  124.     look = normalize(look);
  125.     float3 right = cross(up, look);
  126.  
  127.     //
  128.     // Compute triangle strip vertices (quad) in world space.
  129.     //
  130.     float halfWidth  = 0.5f*gin[0].SizeW.x;
  131.     float halfHeight = 0.5f*gin[0].SizeW.y;
  132.     
  133.     float4 v[4];
  134.     v[0] = float4(gin[0].CenterW + halfWidth*right - halfHeight*up, 1.0f);
  135.     v[1] = float4(gin[0].CenterW + halfWidth*right + halfHeight*up, 1.0f);
  136.     v[2] = float4(gin[0].CenterW - halfWidth*right - halfHeight*up, 1.0f);
  137.     v[3] = float4(gin[0].CenterW - halfWidth*right + halfHeight*up, 1.0f);
  138.  
  139.     //
  140.     // Transform quad vertices to world space and output 
  141.     // them as a triangle strip.
  142.     //
  143.     
  144.     float2 texC[4] = 
  145.     {
  146.         float2(0.0f, 1.0f),
  147.         float2(0.0f, 0.0f),
  148.         float2(1.0f, 1.0f),
  149.         float2(1.0f, 0.0f)
  150.     };
  151.     
  152.     GeoOut gout;
  153.     [unroll]
  154.     for(int i = 0; i < 4; ++i)
  155.     {
  156.         gout.PosH     = mul(v[i], gViewProj);
  157.         gout.PosW     = v[i].xyz;
  158.         gout.NormalW  = look;
  159.         gout.TexC     = texC[i];
  160.         gout.PrimID   = primID;
  161.         
  162.         triStream.Append(gout);
  163.     }
  164. }
  165.  
  166. float4 PS(GeoOut pin) : SV_Target
  167. {
  168.     float3 uvw = float3(pin.TexC, pin.PrimID%3);
  169.     float4 diffuseAlbedo = gTreeMapArray.Sample(gsamAnisotropicWrap, uvw) * gDiffuseAlbedo;
  170.     
  171. #ifdef ALPHA_TEST
  172.     // Discard pixel if texture alpha < 0.1.  We do this test as soon 
  173.     // as possible in the shader so that we can potentially exit the
  174.     // shader early, thereby skipping the rest of the shader code.
  175.     clip(diffuseAlbedo.a - 0.1f);
  176. #endif
  177.  
  178.     // Interpolating normal can unnormalize it, so renormalize it.
  179.     pin.NormalW = normalize(pin.NormalW);
  180.  
  181.     // Vector from point being lit to eye. 
  182.     float3 toEyeW = gEyePosW - pin.PosW;
  183.     float distToEye = length(toEyeW);
  184.     toEyeW /= distToEye; // normalize
  185.  
  186.     // Light terms.
  187.     float4 ambient = gAmbientLight*diffuseAlbedo;
  188.  
  189.     const float shininess = 1.0f - gRoughness;
  190.     Material mat = { diffuseAlbedo, gFresnelR0, shininess };
  191.     float3 shadowFactor = 1.0f;
  192.     float4 directLight = ComputeLighting(gLights, mat, pin.PosW,
  193.         pin.NormalW, toEyeW, shadowFactor);
  194.  
  195.     float4 litColor = ambient + directLight;
  196.  
  197. #ifdef FOG
  198.     float fogAmount = saturate((distToEye - gFogStart) / gFogRange);
  199.     litColor = lerp(litColor, gFogColor, fogAmount);
  200. #endif
  201.  
  202.     // Common convention to take alpha from diffuse albedo.
  203.     litColor.a = diffuseAlbedo.a;
  204.  
  205.     return litColor;
  206. }
  207.  
  208.  
  209.